package com.集合.作业;

import java.util.HashSet;
import java.util.Objects;

@SuppressWarnings("all")
public class h6 {
    /**
     *重写了hashCode方法和equals方法   根据id和 name 来返回 哈希值
     */
    public static void main(String[] args) {
        HashSet s = new HashSet();
        AA a1 = new AA(1001, "AA");
        AA a2 = new AA(1002,"BB");

        s.add(a1);  //添加成功，按照1001和AA计算的 哈希索引  假如位置是 1
        s.add(a2);  //添加成功，按照1002和BB计算的 哈希索引  假如位置是 2
        a1.name = "CC";  //将a1的name改成CC， 索引1 处的key对象的name变成了CC，但不会改变位置，因为已经放进去了；
        s.remove(a1);//现在a1是1001 CC，他会根据1001 CC为哈希查找位置，假如找到了3位置 ， 3位置为null，就删除失败；链表没变化；
        System.out.println(s); //输出是遍历输出，因为a1.name = "CC"把11位置的name搞成了CC，所以输出BB:1002	, CC:1001

        AA a3 = new AA(1001, "CC");//1001 CC
        s.add(a3);  //它会根据1001 CC来计算哈希值；假如计算到了 位置3， 3位置为null，所以放进去了
        System.out.println(s);  //因为a1是根据最开始的1001AA来计算的地址，就算有两个但他们的存放的位置不一样，就会重复；、
        //BB:1002	, CC:1001	, CC:1001

        AA a4 = new AA(1001, "AA");
        //a4会根据1001 AA计算哈希，会计算到1位置，但a1的name不是AA了，所以a1和a4计算的位置一样，但equals不同，所以会放到a1的后面，即：同一个链表；
        s.add(a4);
        System.out.println(s);//[BB:1002	, CC:1001	, CC:1001	, AA:1001	]
    }
}
class AA{
    String name;
    int num;

    public AA(int num,String name ) {
        this.name = name;
        this.num = num;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        AA aa = (AA) o;
        return num == aa.num && Objects.equals(name, aa.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, num);
    }

    @Override
    public String toString() {
        return name+":"+num+"\t";
    }
}